﻿package com.pandemicode.framework.controls {
	import com.pandemicode.framework.interfaces.IDisposeable;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.net.LocalConnection;
	import flash.system.System;
	import flash.text.TextField;
	import flash.utils.Timer;
	import org.osflash.signals.natives.NativeSignal;
	import org.osflash.signals.Signal;
	
	/**
	* @author Michael Lawrence
	* @version 1.0.0
	*/
	public class MemoryUsage extends DefaultTextField implements IDisposeable {
		private var _timer:Timer;
		private var _memoryUsed:int = 0;
		private var _lastMemoryUsed:int = 0;
		
		private var _addedToStage:NativeSignal;
		private var _removedFromStage:NativeSignal;
		private var _timerTick:NativeSignal;
		private var _changed:Signal;
		
		public function get changed():Signal { return this._changed; }
		
		/**
		 * A textfield that displays the memory being used by the current flash file.
		 */
		public function MemoryUsage() {
			super(20, 0xffff00);
			
			this._addedToStage = new NativeSignal(this, Event.ADDED_TO_STAGE, Event);
			this._removedFromStage = new NativeSignal(this, Event.REMOVED_FROM_STAGE, Event);
			this._changed = new Signal();
			
			if (this.stage == null) this._addedToStage.add(this._init);
			else this._init();
			this._removedFromStage.add(this._dispose);
		}
		
		/**
		 * Initializes the class.  Starts the timer that updates the display.
		 * @param	e	The dispatched event.
		 */
		private function _init(e:Event = null):void {
			this._addedToStage.remove(this._init);
			
			this._timer = new Timer(1000);
			this._timerTick = new NativeSignal(this._timer, TimerEvent.TIMER, TimerEvent);
			this._timerTick.add(this.onTick);
			this._timer.start();
		}
		
		/**
		 * Updates the display.
		 * @param	e	The dispatched event.
		 */
		private function onTick(e:TimerEvent):void {
			this._memoryUsed = Number(System.totalMemory / 1024 / 1024);
			if(this._memoryUsed != this._lastMemoryUsed) {
				this.text = "memory: " +  this._memoryUsed.toFixed(2) + "Mb";
				this._lastMemoryUsed = this._memoryUsed;
				this._changed.dispatch();
			}
		}
		
		public function dispose():void {
			this._dispose();
		}
		
		/**
		 * Disposes of the current object.
		 * @param	e	The dispatched event.
		 */
		private function _dispose(e:Event = null):void {
			this._addedToStage.removeAll();
			this._removedFromStage.removeAll();
			this._timerTick.removeAll();
			this._changed.removeAll();
			this._timer.stop();
			this._timer = null;
		}
	}
}
